#ifndef REMOTECORES_PROTOCOL_H_
#define REMOTECORES_PROTOCOL_H_

#include <apr_network_io.h>
#include "remotecores_error.h"

#define REMOTECORES_CHUNK_SIZE (1)

/* D.J. Bernstein wire based protocol */

typedef struct {
    apr_socket_t *sock;
    char buffer[REMOTECORES_CHUNK_SIZE];
    apr_size_t start;
    apr_size_t end;
} remotecores_protocol_t;

remotecores_error_t *
remotecores_protocol_create(remotecores_protocol_t **p, apr_socket_t *sock, 
                            apr_pool_t *pool);

/* Writers */

/** 
 * @brief Serialize and write an apr_off_t onto the wire
 * @param p initialized protocol
 * @param d apr_off_t
 * @return REMOTECORES_SUCCESS on success
 */
remotecores_error_t*
remotecores_offset_write(remotecores_protocol_t *p, apr_off_t *d);

/** 
 * @brief Serialize and write an apr_uint32_t onto the wire
 * @param p initialized protocol
 * @param d apr_uint32_t
 * @return REMOTECORES_SUCCESS on success
 */
remotecores_error_t*
remotecores_uint32_write(remotecores_protocol_t *p, apr_uint32_t *d);

remotecores_error_t*
remotecores_int32_write(remotecores_protocol_t *p, apr_int32_t *d);

remotecores_error_t*
remotecores_string_write(remotecores_protocol_t *p, const char *str);

/* Readers */
remotecores_error_t*
remotecores_offset_read(remotecores_protocol_t *p, apr_off_t *d);

remotecores_error_t*
remotecores_uint32_read(remotecores_protocol_t *p, apr_uint32_t *d);

remotecores_error_t*
remotecores_int32_read(remotecores_protocol_t *p, apr_int32_t *d);

remotecores_error_t*
remotecores_string_read(remotecores_protocol_t *p, char **str);

#endif
